﻿using System;
using System.IO;
using Adaptive.Agrona;
using Adaptive.Agrona.Concurrent;

using Unity.Type.BinaryType;

namespace Unity.Type
{
    public class MetadataSerializer : IUnitySerializer<Metadata>
    {
        private static readonly MessageHeader MessageHeader = new MessageHeader();
        private static readonly Metadata MetadataEncoder = new Metadata();

        private const int MessageLength = MessageHeader.Size + Metadata.BlockLength;

        private readonly IMutableDirectBuffer _encodeBuffer = new UnsafeBuffer(new byte[MessageLength]);

        private byte[] UnityIdToBinary(string value)
        {
            int maxLength = Metadata.UnityIdLength;
            if(value.Length > maxLength)
            {
                throw new IOException("value size more than unityId max length");
            }
            byte[] binary = new byte[maxLength];

            int offset = maxLength - value.Length;
            for(int i = 0; i < maxLength; i++)
            {
                if(i < offset)
                {
                    binary[i] = (byte) '0';
                } 
                else
                {
                    binary[i] = (byte)value[i - offset];
                }
            }
            return binary;
        }
            

        public byte[] Serialize(Metadata obj)
        {
            if(obj == null)
            {
                return Array.Empty<byte>();
            }
            
            Console.WriteLine(this._encodeBuffer.Capacity);
            MetadataEncoder.WrapForEncodeAndApplyHeader(_encodeBuffer, 0, MessageHeader);
            MetadataEncoder.SetUnityId(UnityIdToBinary(obj.GetUnityId()));
            MetadataEncoder.Timestamp = obj.Timestamp;
            MetadataEncoder.Version = obj.Version;
            MetadataEncoder.ChangerCsiId = obj.ChangerCsiId;
            MetadataEncoder.EntityType = obj.EntityType;
            MetadataEncoder.EventType = obj.EventType;
            MetadataEncoder.FormatVer = obj.FormatVer;
            MetadataEncoder.VersionDelete = obj.VersionDelete;
            return _encodeBuffer.ByteArray;
        }
        
    }
}
